package com.koo.modules.api.service.impl;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.koo.common.exception.RRException;
import com.koo.common.utils.MyStrUtil;
import com.koo.modules.api.mapper.DefaultDownloadMapper;
import com.koo.modules.api.model.*;
import com.koo.modules.api.service.DownloadApiService;
import com.koo.modules.b2b.dao.B2bStoreToOutStoreDao;
import com.koo.modules.quartz.constant.B2BConstant;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Service
@Slf4j
public class DownloadApiServiceImpl implements DownloadApiService {

    private Integer productDownloadCount = B2BConstant.MAX_LIMIT_SIZE.getNumber();

    @Autowired
    private B2bStoreToOutStoreDao b2bStoreToOutStoreDao;

    @Autowired
    private DefaultDownloadMapper defaultDownloadMapper;

    @Override
    public Map<String, Object> downloadProductData(Map<String, Object> paramMap) {
        String storeId = (String) paramMap.get("storeId");
        JSONArray downloadRecords = JSON.parseArray(paramMap.get("downloadRecords").toString());
        List<XXBaseProduct> products = new ArrayList<>();
        List<Map<String, Object>> prefixes = listPrefixByStoreId(storeId, true);
        if (MyStrUtil.isEmpty(prefixes) || prefixes.isEmpty()) {
            log.error(storeId + ":未绑定企业.");
            return returnMap(products, new RRException("该门店未绑定企业."));
        }
        Map<String, Object> queryMap = new ConcurrentHashMap<>();
        try {
            queryMap.put("limit", productDownloadCount);
            for (int i = 0 ,end = prefixes.size(); i < end; i++) {
                String prefix = prefixes.get(i).get("companyCode").toString();
                queryMap.put("prefix", prefix);
                for(int j = 0, recordEnd = downloadRecords.size(); j < recordEnd; j++) {
                    JSONObject record = downloadRecords.getJSONObject(j);
                    String addDate = DateUtil.formatDateTime(record.getDate("downloadDate"));
                    if(record.getString("remark").equals(prefix) && MyStrUtil.isNotEmpty(addDate)) {
                        String productId = record.getString("maxDownloadId");
                        queryMap.put("where", " (modifyDate = '" + addDate + "' and productId > '" + productId + "') or modifyDate > '" + addDate + "' ");
                        break;
                    }
                }
                List<XXBaseProduct> prefixList = defaultDownloadMapper.listProductByMap(queryMap);
                products.addAll(prefixList);
                //满足一次查询的数量,直接返回,不满足时,查询不足的数量
                if(products.size() == productDownloadCount){
                    break;
                } else {
                    queryMap.put("limit", productDownloadCount - products.size());
                }
            }
        } catch (Exception e) {
            log.error("下载商品数据错误", e);
            return returnMap(products, e);
        }
        return returnMap(convertList(products, new XXBaseProduct(), null), null);
    }

    @Override
    public Map<String, Object> downloadOutOrderData(Map<String, Object> paramMap) {
        String storeId = (String) paramMap.get("storeId");
        JSONArray downloadRecords = JSON.parseArray(paramMap.get("downloadRecords").toString());
        List<XXOutOrder> orders = new ArrayList<>();
        List<XXOutOrderDetail> details = new ArrayList<>();
        List<Map<String, Object>> prefixes = listPrefixByStoreId(storeId, false);
        Map<String, Object> resultMap = new ConcurrentHashMap<>();
        if (MyStrUtil.isEmpty(prefixes) || prefixes.isEmpty()) {
            log.error(storeId + ":未绑定企业.");
            return returnMap(resultMap, new RRException("该门店未绑定企业."), 0);
        }
        Map<String, Object> queryMap = new ConcurrentHashMap<>();
        try {
            String relationCode = null;
            for(int i = 0,end = prefixes.size(); i < end; i++){
                String prefix = prefixes.get(i).get("companyCode").toString();
                String outStoreId = prefixes.get(i).get("outStoreId").toString();
                queryMap.put("prefix", prefix);
                queryMap.put("outStoreId", outStoreId);
                //根据绑定的外部storeId,查询对应前缀的外部门店号(外部门店号是不同批发商的门店号)
                XXBaseStoreInfo outStore = b2bStoreToOutStoreDao.selectOutStoreCodeByPrefix(queryMap);
                queryMap.put("storeCode", outStore.getStoreCode());
                for(int j = 0, recordEnd = downloadRecords.size(); j < recordEnd; j++) {
                    JSONObject record = downloadRecords.getJSONObject(j);
                    String addDate = DateUtil.formatDateTime(record.getDate("downloadDate"));
                    if(record.getString("remark").equals(prefix) && MyStrUtil.isNotEmpty(addDate)) {
                        queryMap.put("where", " modifyDate > '" + addDate + "' ");
                        break;
                    } else {
                        queryMap.put("where", " 1 = 1 ");
                    }
                }
                List<XXOutOrder> prefixOutOrder = defaultDownloadMapper.listOutOrderByMap(queryMap);
                if(MyStrUtil.isNotEmpty(prefixOutOrder) && prefixOutOrder.size() > 0){
                    orders.addAll(prefixOutOrder);
                    queryMap.put("orders", prefixOutOrder);
                    List<XXOutOrderDetail> prefixOutDetail = defaultDownloadMapper.listOutOrderDetailByMap(queryMap);
                    String dataSource = defaultDownloadMapper.findPrefixDataSource(queryMap);
                    setDataSource(prefixOutDetail, dataSource);
                    details.addAll(prefixOutDetail);
                }

            }
            resultMap.put("purchaseStorageInspectionOrder", convertList(orders, new XXOutOrder(), storeId));
            resultMap.put("purchaseStorageInspectionOrderDetail", convertList(details, new XXOutOrderDetail(), storeId));
        } catch (Exception e) {
            log.error("下载出库数据错误",e);
            return returnMap(resultMap, e, -1);
        }
        return returnMap(resultMap, null, orders.size());
    }

    @Override
    public List<Map<String, Object>> listPrefixByStoreId(String storeId, boolean isProduct) {
        return b2bStoreToOutStoreDao.listPrefixByStoreId(storeId, isProduct);
    }

    @Override
    public Map<String, Object> findDownloadCount(Map<String, Object> paramMap) {
        String tableName = (String) paramMap.get("tableName");
        String storeId = (String) paramMap.get("storeId");
        JSONArray downloadRecords = JSON.parseArray(paramMap.get("downloadRecords").toString());
        boolean isProduct = true;
        Map<String, Object> queryMap = new ConcurrentHashMap<>();
        Map<String, Object> resultMap = new ConcurrentHashMap<>();
        if(tableName.equals("baseProduct")){
            queryMap.put("tableName", "BaseProduct");
        } else {
            queryMap.put("tableName", "OutOrder");
            isProduct = false;
        }
        Integer count = 0;
        resultMap.put("count", count);
        //查询已经绑定的企业前缀
        List<Map<String, Object>> prefixes = listPrefixByStoreId(storeId, isProduct);
        if (MyStrUtil.isEmpty(prefixes) || prefixes.isEmpty()) {
            log.error(storeId + ":未绑定企业.");
            resultMap.put("msg", "该门店未绑定企业.");
            return resultMap;
        }
        if(MyStrUtil.isEmpty(tableName)){
            return resultMap;
        }
        queryMap.put("isProduct", isProduct);
        try {
            for(int i = 0,end = prefixes.size(); i < end; i++){
                String prefix = prefixes.get(i).get("companyCode").toString();
                queryMap.put("prefix", prefix);
                if(!isProduct) {
                    String outStoreId = prefixes.get(i).get("outStoreId").toString();
                    queryMap.put("outStoreId", outStoreId);
                    //根据绑定的外部storeId,查询对应前缀的外部门店号(外部门店号是不同批发商的门店号)
                    XXBaseStoreInfo outStore = b2bStoreToOutStoreDao.selectOutStoreCodeByPrefix(queryMap);
                    queryMap.put("storeCode", outStore.getStoreCode());
                }
                if(downloadRecords.size() == 0) {
                    queryMap.put("where", " 1 = 1 ");
                }
                for(int j = 0, recordEnd = downloadRecords.size(); j < recordEnd; j++) {
                    JSONObject record = downloadRecords.getJSONObject(j);
                    String addDate = DateUtil.formatDateTime(record.getDate("downloadDate"));
                    if(record.getString("remark").equals(prefix) && MyStrUtil.isNotEmpty(addDate)) {
                        String productId = record.getString("maxDownloadId");
                        queryMap.put("where", isProduct ?
                                " (modifyDate = '" + addDate + "' and productId > '" + productId + "') or modifyDate > '" + addDate + "' " :
                                " modifyDate > '" + addDate + "' ");
                        break;
                    } else {
                        queryMap.put("where", " 1 = 1 ");
                    }
                }
                //在查询数量
                count += defaultDownloadMapper.findDodnloadCountByMap(queryMap);
            }
            resultMap.put("count", count);
        } catch (Exception e) {
            log.error("查询下载数量错误",e);
            resultMap.put("msg", e.getMessage());
            return resultMap;
        }
        return resultMap;
    }


    private <T> Map<String, Object> returnMap(List<T> list, Exception e){
        return warpMap(list, e, list.size());
    }

    private Map<String, Object> returnMap(Map<String, Object> resultMap, Exception e, Integer deteilSize) {
        return warpMap(resultMap, e, deteilSize);
    }

    private Map<String, Object> warpMap(Object data, Exception e, Integer count){
        Map<String, Object> returnMap = new ConcurrentHashMap<>();
        returnMap.put("state", 200);
        returnMap.put("msg", "获取数据成功.");
        if(MyStrUtil.isNotEmpty(e)){
            returnMap.put("state", 500);
            returnMap.put("msg", "数据获取失败,"+e.getMessage());
            return returnMap;
        }
        returnMap.put("total", count);
        returnMap.put("data", data);
        if(count == 0){
            returnMap.put("msg", "暂无数据更新.");
        }
        return returnMap;
    }

    /**
     * 转换 查询出的列表格式
     * [[0],[1],[2]]
     * 数据 : [0]
     * productCode(如果是商品表) : [1]
     * 字段列表(不是商品表时 : 下标为1) : [2]
     * @param dataList 数据列表
     * @return
     */
    private <T> List<Object> convertList(List<T> dataList, T t, String relationCode) {
        Field[] fields = null;
        boolean isProduct = false;
        if(t instanceof XXBaseProduct){
            isProduct = true;
            fields = XXBaseProduct.class.getDeclaredFields();
        } else if (t instanceof XXOutOrder){
            fields = XXOutOrder.class.getDeclaredFields();
        } else if (t instanceof XXOutOrderDetail){
            fields = XXOutOrderDetail.class.getDeclaredFields();
        }
        List<Object> result = new ArrayList<>();

        List<String> codeList = new ArrayList<>();
        codeList.add("productCode");
        List<String> nameList = new ArrayList<>();

        try {
            for(T data : dataList){
                List<Object> datas = new ArrayList<>();
                for(Field field : fields){
                    if(Modifier.isFinal(field.getModifiers())){
                        continue;// 过滤final字段
                    }
                    String rowName = field.getName();
                    field.setAccessible(true);
                    Object value = field.get(data);
                    if(rowName.equals("storeId")){
                        datas.add(relationCode);
                    } else {
                        datas.add(value);
                    }
                    if(isProduct && rowName.equals("productCode")){
                        codeList.add(value.toString());
                    }
                }
                result.add(datas);
            }
            for(Field field : fields){
                if(Modifier.isFinal(field.getModifiers())){
                    continue;// 过滤final字段
                }
                nameList.add(field.getName());
            }
            if(isProduct){
                result.add(codeList);
            }
            result.add(nameList);
        } catch (IllegalArgumentException | IllegalAccessException e) {
            e.printStackTrace();
        }
        return result;
    }

    private void setDataSource(List<? extends OrderDataInterface> lists, String dataSource) {
        for(OrderDataInterface model : lists){
            model.setDataSource(dataSource);
        }
    }

}
